package com.springboot.file.provider;

import com.alibaba.excel.annotation.ExcelProperty;
import com.springboot.file.util.easyexcel.annotation.EasyExport;
import com.springboot.file.util.easyexcel.constant.BusinessType;
import com.springboot.file.util.easyexcel.provider.ExportProvider;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 发票导出服务提供者示例
 * 实现ExportProvider接口，并使用@EasyExport注解标注，自动注册到导出服务中
 */
@Slf4j
@Component
@EasyExport(value = BusinessType.INVOICE, description = "发票清单导出")
public class InvoiceExportProvider implements ExportProvider<InvoiceExportProvider.InvoiceExportDTO> {

    @Override
    public long getExportDataCount(Map<String, Object> params) {
        // 实际业务中，需要根据导出条件查询数据库获取总数
        // 这里仅作示例，返回模拟数据
        log.info("查询发票导出总数，参数: {}", params);
        return 100000; // 模拟返回1000000条数据
    }

    @Override
    public List<InvoiceExportDTO> getExportData(Map<String, Object> params, int pageNum, int pageSize) {
        // 实际业务中，需要根据导出条件和分页参数查询数据库
        // 这里仅作示例，返回模拟数据
        log.info("查询发票导出数据，参数: {}, 页码: {}, 每页数量: {}", params, pageNum, pageSize);
        
        // 计算本页的开始和结束索引，使用long防止整数溢出
        long longStartIndex = (long)(pageNum - 1) * (long)pageSize;
        int startIndex = (int)longStartIndex; // 安全转换回int，因为在实际场景中索引不会超过Integer.MAX_VALUE
        int endIndex = (int) Math.min(startIndex + pageSize, getExportDataCount(params));
        
        // 生成模拟数据
        List<InvoiceExportDTO> result = new ArrayList<>();
        for (int i = startIndex; i < endIndex; i++) {
            InvoiceExportDTO dto = new InvoiceExportDTO();
            dto.setInvoiceId("INV" + (10000 + i));
            dto.setInvoiceNo("FP" + (20000 + i));
            dto.setCustomerName("客户" + (i % 100));
            dto.setInvoiceDate(LocalDate.now().minusDays(i % 30));
            dto.setInvoiceAmount(new BigDecimal("" + (1000 + i % 9000) + "." + (i % 100)));
            dto.setTaxRate(new BigDecimal("0." + (i % 17)));
            dto.setTaxAmount(dto.getInvoiceAmount().multiply(dto.getTaxRate()));
            dto.setTotalAmount(dto.getInvoiceAmount().add(dto.getTaxAmount()));
            dto.setRemark("这是发票" + dto.getInvoiceId() + "的备注");
            result.add(dto);
        }
        
        // 应用过滤条件（如果有）
        if (params != null && params.containsKey("customerName")) {
            String customerNameFilter = (String) params.get("customerName");
            result = result.stream()
                    .filter(dto -> dto.getCustomerName().contains(customerNameFilter))
                    .collect(Collectors.toList());
        }
        
        return result;
    }

    @Override
    public Class<InvoiceExportDTO> getEntityClass() {
        return InvoiceExportDTO.class;
    }
    
    @Override
    public String getSheetName() {
        return "发票清单";
    }
    
    /**
     * 发票导出DTO
     * 使用@ExcelProperty注解定义Excel表头
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class InvoiceExportDTO {
        @ExcelProperty("发票ID")
        private String invoiceId;
        
        @ExcelProperty("发票号码")
        private String invoiceNo;
        
        @ExcelProperty("客户名称")
        private String customerName;
        
        @ExcelProperty("开票日期")
        private LocalDate invoiceDate;
        
        @ExcelProperty("不含税金额")
        private BigDecimal invoiceAmount;
        
        @ExcelProperty("税率")
        private BigDecimal taxRate;
        
        @ExcelProperty("税额")
        private BigDecimal taxAmount;
        
        @ExcelProperty("价税合计")
        private BigDecimal totalAmount;
        
        @ExcelProperty("备注")
        private String remark;
    }
} 